#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <fcntl.h>

#include "procmsg.h"
#include "uart.h"

/********************************
********** AT Commands **********
*********************************/

/*<----- General Commands ----->*/

//Repeat last command
int AT_Repeat(int fd, char *rxbuf){

    int txnum=1;
    int nwrite=0;

    int rxnum=0;
    int msgnum=0;

    //Write Command
    nwrite = write(fd,"\r",txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Try baud rate divisor
int AT_Set_BRD(int fd,char *rxbuf, unsigned char val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT BRD ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set baud rate timeout
int AT_Set_BRT(int fd,char *rxbuf, unsigned char val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT BRT ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set all settings to defaults
int AT_Defaults(int fd, char *rxbuf){

    int txnum=5;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;


    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT D");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Echo off/on
int AT_Set_Echo(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT E ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Print ELM327 version ID string
int AT_Get_Version(int fd, char *rxbuf){

    int txnum=5;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT I");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Linefeeds  off*/on
int AT_Set_Linefeeds(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT L ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Enter low power mode
int AT_EnterLowPower(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT LP");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Memory  off/on*
int AT_Set_Memory(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT M ",val);
    }


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Warm start
int AT_WarmStart(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT WS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(3,rxbuf,rxnum);

    return msgnum;
}

//Reset device
int AT_Reset(int fd, char *rxbuf){

    int txnum=5;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT Z");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(3,rxbuf,rxnum);

    return msgnum;
}

//Display device desciption
int AT_Get_Description(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT @1");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Display device identifier
int AT_Get_Identifier(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT @2");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Store device identifier
int AT_Set_Identifier(int fd, char *rxbuf,char *info){

    int size=0;
    int maxsize=12;
    size=strlen(info);

    if(size>maxsize)
        size = maxsize;

    int txnum=7+maxsize;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    int i;

    //Set Command
    memset(txbuf,0,txnum+1);

    txbuf[0] = 'A';
    txbuf[1] = 'T';
    txbuf[2] = 0x20;
    txbuf[3] = '@';
    txbuf[4] = '3';
    txbuf[5] = 0x20;

    for(i=0;i<size;i++){

        txbuf[6+i]=info[i];
    }

    for(i=size;i<maxsize;i++){

        txbuf[6+i]=0x20;
    }

    txbuf[txnum-1] = 0x0d;

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}



/*<----- Programmable Parameter Commands ----->*/

//Disable PP xx
int AT_Set_PP_OFF(int fd,char *rxbuf,char pp){

    int txnum=13;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x%s\r","AT PP ",pp," OFF");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//All PPs off
int AT_PP_OFF(int fd, char *rxbuf){

    int txnum=13;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;


    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT PP FF OFF");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Enable PP xx
int AT_Set_PP_ON(int fd,char *rxbuf,char pp){

    int txnum=12;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x%s\r","AT PP ",pp," ON");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//All PPs on
int AT_PP_ON(int fd, char *rxbuf){

    int txnum=12;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;


    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT PP FF ON");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//For PP xx, set value to yy
int AT_Set_PP_VAL(int fd,char *rxbuf, unsigned char pp,unsigned char val){

    int txnum=15;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x%s%02x\r","AT PP ",pp," SV ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Print PP summary
int AT_Get_PPSummary(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT PPS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(4,rxbuf,rxnum);

    return msgnum;
}




/*<----- Voltage Reading Commands ----->*/

//Calibrate voltage to dd.dd volts
int AT_Set_CV(int fd,char *rxbuf,int val){

    int txnum=11;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%04d\r","AT CV ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Read voltage
int AT_Get_Voltage(int fd,char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT RV");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


/*<----- Other Commands ----->*/

//Read SLEEP input level
int AT_Get_Sleep(int fd,char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT IGN");


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

/*<----- OBD Commands ----->*/

//Allow long (>7byte) message
int AT_AllowLong(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT AL");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Automatically receive
int AT_AutoReceive(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT AR");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Adaptive timing off,auto1*,auto2
int AT_Set_ADTiming(int fd,char *rxbuf, unsigned char val){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '2'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT AT ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Bypass initialization sequence
int AT_BypassInit(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT BI");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Describe current protocol
int AT_Get_Protocol(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT DP");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Describe current protocol by number
int AT_Get_ProtocolNumber(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT DPN");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Header off*/on
int AT_Set_Header(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT H",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Monitor All
int AT_MonitorAll(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT MA");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Monitor for receive address to hh
int AT_Set_MonitorRev(int fd,char *rxbuf,int val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT MR ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Monitor for transmitter address to hh
int AT_Set_MonitorTran(int fd,char *rxbuf,int val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT MT ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Normal length messages*(7 bytes max)
int AT_NormalLength(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT NL");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Protocol close
int AT_ProtocolClose(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT PC");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Responses off*/on
int AT_Set_Responses(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT R ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set the receive address to hh
int AT_Set_RevAddress(int fd,char *rxbuf,int val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT RA ",val);
    //sprintf(txbuf,"%s%02x\r","AT SR ",val);
    //Two commands are same


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Print spaces off/on*
int AT_Set_Space(int fd,char *rxbuf, unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT S ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set header to hhh
int AT_Set_HeaderValue_A(int fd,char *rxbuf,int val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x\r","AT SH ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set header to hh hh hh
int AT_Set_HeaderValue_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3){

    int txnum=15;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x\r","AT SH ",val1,val2,val3);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set protocol to h and save it
int AT_Set_Protocol(int fd,char *rxbuf, unsigned char val){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>12){
        printf("The input parameter must be '0' --'C'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT SP ",val);
		  //sprintf(txbuf, "AT SP %x\r", val);			
		  //printf("Command: %s\n", txbuf);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set protocol to h and save it
int AT_Set_ProtocolAuto(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>12){
        printf("The input parameter must be '0' --'C'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT SP A",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set timeout to hh x 4ms
int AT_Set_Timeout(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT ST ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Try protocol
int AT_Try_Protocol(int fd,char *rxbuf, unsigned char val){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>12){
        printf("The input parameter must be '0' --'C'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT TP ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Try protocol with auto search
int AT_Try_ProtocolAuto(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>12){
        printf("The input parameter must be '0' --'C'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT TP A",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


/*<----- J1850 Specific Commands ----->*/

//IFRs off,auto*,or on
int AT_Set_IFR(int fd, char *rxbuf,unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '2'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT IFR ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//IFRs off,auto*,or on
int AT_Set_IFR_Source(int fd, char *rxbuf,unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val!='H' && val!='S'){
        printf("The input parameter must be 'H' or 'S'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%c\r","AT IFR ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}



/*<----- ISO Specific Commands ----->*/

//Set ISO baud rate to 10400
int AT_ISO_Set_BDR_10(int fd, char *rxbuf){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT IB 10");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set ISO baud rate to 9600
int AT_ISO_Set_BDR_96(int fd, char *rxbuf){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT IB 96");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set the ISO(slow) init adress tohh
int AT_ISO_Set_InitAddr(int fd,char *rxbuf, unsigned char val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT IIA ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Display ISO key word
int AT_ISO_Get_Keyword(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT KW");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Key word checking off/on*
int AT_ISO_Set_Keyword(int fd, char *rxbuf,unsigned char val){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT KW ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set wakeup interval to hh x20 ms
int AT_ISO_Set_WakeupInterval(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT SW ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set wakeup message
int AT_ISO_Set_WakeupMSG(int fd, char *rxbuf,unsigned char *info,int size){

    int maxsize=6;

    if(size>maxsize)
        size = maxsize;

    int txnum=7+size*2+(size-1) ;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    int i;
    char *ptr;

    ptr=txbuf;

    //Set Command
    memset(txbuf,0,txnum+1);
    /*
    txbuf[0] = 'A';
    txbuf[1] = 'T';
    txbuf[2] = 0x20;
    txbuf[3] = 'W';
    txbuf[4] = 'M';
    txbuf[5] = 0x20;
    */

    sprintf(txbuf,"%s","AT WM ");
    ptr+=6;

    for(i=0;i<size;i++){

        sprintf(ptr,"%02x ",info[i]);
        ptr+=3;
    }

    txbuf[txnum-1] = 0x0d;

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Automatic formatting off/on*
int AT_ISO_Set_AutoFormat(int fd, char *rxbuf,unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT CAF ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set ID filter to hhh
int AT_ISO_Set_Filter_A(int fd,char *rxbuf,int val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x\r","AT CF ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set ID filter to hh hh hh hh
int AT_ISO_Set_Filter_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3,unsigned char val4){

    int txnum=18;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x %02x\r","AT CF ",val1,val2,val3,val4);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Flow control off/on*
int AT_ISO_Set_FlowControl(int fd, char *rxbuf,unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT CFC ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set ID mask to hhh
int AT_ISO_Set_Mask_A(int fd,char *rxbuf,int val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x\r","AT CM ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set ID mask to hh hh hh hh
int AT_ISO_Set_Mask_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3,unsigned char val4){

    int txnum=18;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x %02x\r","AT CM ",val1,val2,val3,val4);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set CAN priority to hh(29 bit only)
int AT_ISO_Set_Priority(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x\r","AT CP ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set CAN recieve address to hhh
int AT_ISO_Set_RevAddr_A(int fd,char *rxbuf,int val){

    int txnum=11;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x\r","AT CRA ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set CAN recieve address to hh hh hh hh
int AT_ISO_Set_RevAddr_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3,unsigned char val4){

    int txnum=19;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x %02x\r","AT CRA ",val1,val2,val3,val4);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Show CAN status counts
int AT_ISO_Get_StatusCounts(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT CS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Display of the DLC off/on*
int AT_ISO_Set_DLCDisplay(int fd, char *rxbuf,unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT D ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Flow control,set mode to h
int AT_ISO_Set_FC_mode(int fd,char *rxbuf, unsigned char val){

    int txnum=11;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '2'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT FC SM ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Flow control,set header to hhh
int AT_ISO_Set_FCHeader_A(int fd,char *rxbuf,int val){

    int txnum=13;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x\r","AT FC SH ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Flow control,set header to hh hh hh hh
int AT_ISO_Set_FCHeader_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3,unsigned char val4){

    int txnum=21;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x %02x\r","AT FC SH ",val1,val2,val3,val4);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Flow control,set data to [...]
int AT_ISO_Set_FCData(int fd, char *rxbuf,unsigned char *info,int size){

    int maxsize=5;

    if(size>maxsize)
        size = maxsize;

    int txnum=10+size*2+(size-1) ;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    int i;
    char *ptr;

    ptr=txbuf;

    //Set Command
    memset(txbuf,0,txnum+1);

    sprintf(txbuf,"%s","AT FC SD ");
    ptr+=9;

    for(i=0;i<size;i++){

        sprintf(ptr,"%02x ",info[i]);
        ptr+=3;
    }

    txbuf[txnum-1] = 0x0d;

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Send an RTR message
int AT_ISO_SendRTR(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT RTR");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Use of variable DLC off*/on
int AT_ISO_Set_DLCUse(int fd, char *rxbuf,unsigned char val){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>2){
        printf("The input parameter must be '0' ~ '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","AT V ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}



/*<----- J1939 CAN Specific Commands ----->*/

//Monitor for DM1 messages
int AT_Get_DM1(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT DM1");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Use J1939 ELM data format*
int AT_Set_ELM(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT JE");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Use J1939 SAE data format
int AT_Set_SAE(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","AT JS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Monitor for PGN 0hhhh
int AT_Set_PGNMonitor_A(int fd,char *rxbuf,unsigned char  val1,unsigned char val2){

    int txnum=12;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x\r","AT MP ",val1,val2);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Monitor for PGN hh hh hh
int AT_Set_PGNMonitor_B(int fd,char *rxbuf,unsigned char val1,unsigned char val2,unsigned char val3){

    int txnum=15;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%02x %02x %02x\r","AT MP ",val1,val2,val3);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


/********************************
********** ST Commands **********
*********************************/

/*<----- General ----->*/

//Switch UART baud rate in software-friendly way
int ST_Set_BRD_Software(int fd,char *rxbuf,long val){

    int size=0;
    size=getIntnum(val);

    int txnum=7+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%ld\r","ST BR ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set UART baud rate switch timeout
int ST_Set_BRT(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=8+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST BRT ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}

//Set AT@1 device description string
int ST_Set_Description(int fd, char *rxbuf,char *info){

    int size=0;
    size=strlen(info);

    int maxsize=16;
    if(size>maxsize)
        size = maxsize;

    int txnum=8+maxsize;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    int i;

    //Set Command
    memset(txbuf,0,txnum+1);

    txbuf[0] = 'S';
    txbuf[1] = 'T';
    txbuf[2] = 0x20;
    txbuf[3] = 'S';
    txbuf[4] = '@';
    txbuf[5] = '1';
    txbuf[6] = 0x20;

    for(i=0;i<size;i++){

        txbuf[7+i]=info[i];
    }

    for(i=size;i<maxsize;i++){

        txbuf[7+i]=0x20;
    }

    txbuf[txnum-1] = 0x0d;

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set ATI device ID string
int ST_Set_DeviceID(int fd, char *rxbuf,char *info){

    int size=0;
    size=strlen(info);

    int maxsize=12;
    if(size>maxsize)
        size = maxsize;

    int txnum=9+maxsize;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    int i;

    //Set Command
    memset(txbuf,0,txnum+1);

    txbuf[0] = 'S';
    txbuf[1] = 'T';
    txbuf[2] = 0x20;
    txbuf[3] = 'S';
    txbuf[4] = 'A';
    txbuf[5] = 'T';
    txbuf[6] = 'I';
    txbuf[7] = 0x20;

    for(i=0;i<size;i++){

        txbuf[8+i]=info[i];
    }

    for(i=size;i<maxsize;i++){

        txbuf[8+i]=0x20;
    }

    txbuf[txnum-1] = 0x0d;

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Switch UART baud rate in terminal-friendly way
int ST_Set_BRD_Terminal(int fd,char *rxbuf,long val){

    int size=0;
    size=getIntnum(val);

    int txnum=8+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%ld\r","ST SBR ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Write current UART baud rate to NVM
int ST_Set_BRtoNVM(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST WBR");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}



/*<----- Device ID ----->*/

//Print device hardware ID string
int ST_Get_DeivceID(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST DI");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Print firmware ID string
int ST_Get_FirmwareID(int fd, char *rxbuf){

    int txnum=5;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST I");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Print device manufacture ID string
int ST_Get_ManufactureID(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST MFR");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Print device serial number
int ST_Get_SerialNum(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST SN");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


/*<----- PowerSave ----->*/

//Print active PowerSave configuration summary
int ST_Get_PowerSaveConfig(int fd, char *rxbuf){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST SLCS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(5,rxbuf,rxnum);

    return msgnum;
}

//Enter sleep mode with optional delay
int ST_EnterSleep(int fd,char *rxbuf,long val){

    int size=0;
    size=getIntnum(val);

    int txnum=10+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%ld\r","ST SLEEP ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}

//Report last sleep/wakeup triggers
int ST_Get_LastSWTrigger(int fd, char *rxbuf){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST SLLT");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set PWR_CTRL output polarity 0*
int ST_Set_Output_Polarity(int fd,char *rxbuf, unsigned char val){

    int txnum=11;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","ST SLPCP ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//UART sleep/wakeup trigger on/off
int ST_Set_UartSW_Trigger(int fd,char *rxbuf, unsigned char sleep,unsigned char wake){

    char *s1[3]={"off","on"};

    if(sleep>1 || wake>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }


    int txnum = 9 +strlen(s1[sleep])+strlen(s1[wake]);
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    sprintf(txbuf,"%s%s,%s\r","ST SLU ",s1[sleep],s1[wake]);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Set UART inactivity timeout
int ST_Set_UartInactivityTimeout(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=10+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST SLUIT ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}


//Set UART wakeup pulse timing
int ST_Set_UartWakeTiming(int fd,char *rxbuf,unsigned int min,unsigned int max){

    int size=0;
    size=getIntnum(min)+getIntnum(max);

    int txnum=11+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d,%d\r","ST SLUWP ",min,max);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}


//External sleep trigger on/off
int ST_Set_ExternalSW_Trigger(int fd,char *rxbuf, unsigned char sleep,unsigned char wake){

    char *s1[3]={"off","on"};

    if(sleep>1 || wake>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }


    int txnum = 9 +strlen(s1[sleep])+strlen(s1[wake]);
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    sprintf(txbuf,"%s%s,%s\r","ST SLX ",s1[sleep],s1[wake]);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set polarity of the external sleep control input
int ST_Set_ExternalPolarity(int fd,char *rxbuf, unsigned char val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%01x\r","ST SLXP ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Print external SLEEP input status
int ST_Get_ExternalStatus(int fd, char *rxbuf){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST SLXS");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set minimum active time for external sleep trigger before entering sleep
int ST_Set_MinActiveTime(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=10+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST SLXST ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}

//Set minimum inactive time for external sleep trigger before entering sleep
int ST_Set_MinInactiveTime(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=10+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST SLXWT ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}



/*<----- ISO Specific ----->*/

//Turn adaptive maximum interbyte timeing(P1 max) off/on*
int ST_ISO_Set_MaxTiming(int fd,char *rxbuf, unsigned char val){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","ST IAT ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set ISO baud rate
int ST_ISO_Set_BR(int fd,char *rxbuf,long val){

    int size=0;
    size=getIntnum(val);

    int txnum=8+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%ld\r","ST IBR ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Turn ISO manual checksum off*/on
int ST_ISO_Set_ManChecksum(int fd,char *rxbuf, unsigned char val){

    int txnum=10;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);

    if(val>1){
        printf("The input parameter must be '0' or '1'\n");
        return -1;
    }
    else{
        sprintf(txbuf,"%s%01x\r","ST IMCS ",val);
    }

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Set maxinum interbyte time for receiving messages(P1 max)
int ST_ISO_Set_MaxtimeRev(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=9+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST IP1X ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}

//Set interbyte time for transmitting messages(P4)
int ST_ISO_Set_TimeTransmit(int fd,char *rxbuf,unsigned int val){

    int size=0;
    size=getIntnum(val);

    int txnum=8+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%d\r","ST IP4 ",val);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;


}



/*<----- CAN Specific ----->*/

//Add flow control 11-bit ID pair
int ST_Set_FlowControl(int fd,char *rxbuf,int txid,int rxid){

    int txnum=17;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%03x,%03x\r","ST CAFCP ",txid,rxid);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Clear FlowControl
int ST_ClearFlowControl(int fd, char *rxbuf){

    int txnum=9;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST CCFCP");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


/*<----- Monitoring ----->*/

//Monitor OBD bus
int ST_Monitor(int fd, char *rxbuf){

    int txnum=5;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST M");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Monitor all messages on OBD bus
int ST_MonitorAll(int fd, char *rxbuf){

    int txnum=6;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST MA");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}



/*<----- Filtering ----->*/

//Add pass filter
int ST_AddPassFilter(int fd,char *rxbuf,long pattern,long mask){

    int psize=getHexnum(pattern);
    int msize=getHexnum(mask);

    if((pattern>0xFFFFF) || (mask>0xFFFFF)){
        printf("The input parameter must be less 5 bytes\n");
        return -1;
    }

    if(psize!=msize){
        printf("The input parameter must be the same size\n");
        return -1;
    }

    int size=0;
    size=psize+msize;

    int txnum=9+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%x,%x\r","ST FAP ",pattern,mask);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Add block filter
int ST_AddBlockFilter(int fd,char *rxbuf,long pattern,long mask){

    int psize=getHexnum(pattern);
    int msize=getHexnum(mask);

    if((pattern>0xFFFFF) || (mask>0xFFFFF)){
        printf("The input parameter must be less 5 bytes\n");
        return -1;
    }

    if(psize!=msize){
        printf("The input parameter must be the same size\n");
        return -1;
    }

    int size=0;
    size=psize+msize;

    int txnum=9+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%x,%x\r","ST FAB ",pattern,mask);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Add flow control filter
int ST_AddFCFilter(int fd,char *rxbuf,long pattern,long mask){

    int psize=getHexnum(pattern);
    int msize=getHexnum(mask);

    if((pattern>0xFFFFF) || (mask>0xFFFFF)){
        printf("The input parameter must be less 5 bytes\n");
        return -1;
    }

    if(psize!=msize){
        printf("The input parameter must be the same size\n");
        return -1;
    }

    int size=0;
    size=psize+msize;

    int txnum=10+size;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s%x,%x\r","ST FAFC ",pattern,mask);


    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send AT Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}


//Clear all Pass filters
int ST_ClearPassFilters(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST FCP");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Clear all Block filters
int ST_ClearBlockFilters(int fd, char *rxbuf){

    int txnum=7;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST FCB");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}

//Clear all Flow Control filters
int ST_ClearFCFilters(int fd, char *rxbuf){

    int txnum=8;
    int nwrite=0;
    char txbuf[txnum+1];

    int rxnum=0;
    int msgnum=0;

    //Set Command
    memset(txbuf,0,txnum+1);
    sprintf(txbuf,"%s\r","ST FCFC");

    //Write Command
    nwrite = write(fd,txbuf,txnum);

    if(nwrite < txnum){

        printf("Send ST Command Failed,Sent %d byte(s)!\n",nwrite);
        return -1;
    }

    //Read from OBD
    rxnum = ReadData(fd,rxbuf);

    //Process Data
    msgnum = ProcessMessage(1,rxbuf,rxnum);

    return msgnum;
}







